package org.mcjug.locationmailer.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import oauth.signpost.OAuth;

import org.mcjug.locationmailer.R;
import org.mcjug.locationmailer.model.Email;
import org.mcjug.locationmailer.model.StatusMessage;
import org.mcjug.locationmailer.model.template.TemplateItemContainer;
import org.mcjug.locationmailer.oauth.xauth.XoauthAuthenticator;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.preference.PreferenceManager;
import android.text.TextUtils;
//import android.util.Log;

import com.sun.mail.smtp.SMTPTransport;

public class EmailUtil {
    public static final String EMAIL_ADDRESS = "emailAddress";
    public static final String EMAIL_ADDRESS_STATE = "emailAddressState";

    public static List<String> getRecipients(SharedPreferences prefs) {
        List<String> emailAddressList = getCSVList(prefs, EMAIL_ADDRESS);
        List<String> emailAddressStateList = getCSVList(prefs, EMAIL_ADDRESS_STATE);
        if (emailAddressList == null || emailAddressStateList == null) {
            return null;
        }

        List<String> recipients = new ArrayList<String>();
        boolean isActive;
        for (int i = 0; i < emailAddressList.size(); i++) {
            isActive = Boolean.parseBoolean(emailAddressStateList.get(i));
            if (isActive) {
                recipients.add(emailAddressList.get(i));
            }
        }
        return recipients;
    }

    public static List<String> getCSVList(SharedPreferences prefs, String key) {
        List<String> list = new ArrayList<String>();
        String str = prefs.getString(key, null);
        if (str != null) {
            list = new ArrayList<String>(Arrays.asList(str.split(",")));
        }
        return list;
    }

    public static String getCSVString(List<String> list, String delimiter) {
        if (list == null || list.isEmpty())
            return "";

        StringBuilder strBuilder = new StringBuilder();
        for (String str : list) {
            strBuilder.append(str + delimiter);
        }
        strBuilder.delete(strBuilder.length() - delimiter.length(), strBuilder.length());

        return strBuilder.toString();
    }

    public static void sendEmail(StatusMessage statusMessage, Context context) throws Throwable {
        try {
            sendEmail(getEmail(statusMessage, context), context);
        } catch (MessagingException me) {
            // Users dislike error messages they can do nothing about, if it failed sending emails we log it quietly and
            // keep going like nothing happenned.
            //Log.e("EmailUtil", "Error sending email " + me.toString());
        } catch (Throwable e) {
            statusMessage.setMessage(context.getString(R.string.msgEmailError));
            throw new Throwable(e);
        }
    }

    public static void sendEmail(Email email, Context context) throws Throwable {
        if (!NetworkConnectivity.isAvailable(context)) {
            return;
        }

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        String oauthToken = prefs.getString(OAuth.OAUTH_TOKEN, null);
        String oauthTokenSecret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, null);
        if (TextUtils.isEmpty(oauthToken) || TextUtils.isEmpty(oauthTokenSecret)) {
            throw new Exception(context.getString(R.string.msgGmailOAuthNoTokens));
        }

        SMTPTransport smtpTransport = XoauthAuthenticator.connectToSmtp("smtp.googlemail.com", 587, email.getSender(),
                oauthToken, oauthTokenSecret, XoauthAuthenticator.getAnonymousConsumer(), true);

        Properties props = System.getProperties();
        props.put("mail.smtps.host", "smtp.gmail.com");
        props.put("mail.smtps.auth", "true");
        Session session = Session.getInstance(props, null);

        List<String> recipients = email.getRecipients();
        for (String recipient : recipients) {
            Message msg = new MimeMessage(session);
            msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient, false));
            msg.setFrom(new InternetAddress(email.getSender()));
            msg.setSubject(email.getSubject());
            msg.setText(email.getBody());
            msg.setHeader("X-Mailer", "Android program");
            msg.setSentDate(new Date());
            smtpTransport.sendMessage(msg, msg.getAllRecipients());
        }
    }

    public static void sendExceptionEmail(String exceptionMsg, Context context) throws Throwable {
        sendEmail(getExceptionEmail(exceptionMsg, context), context);
    }

    public static void sendExceptionEmailIntent(String exceptionMsg, Context context) throws Throwable {
        Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);

        Email email = getExceptionEmail(exceptionMsg, context);
        emailIntent.setType("plain/text");
        emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, email.getRecipients().toArray(new String[0]));
        emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, email.getSubject());
        emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, email.getBody());

        context.startActivity(Intent.createChooser(emailIntent, context.getString(R.string.chooseEmail)));
    }

    public static Email getExceptionEmail(String exceptionMsg, Context context) throws Throwable {
        Email email = new Email();

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        email.setSender(prefs.getString(Constants.PREFS_SENDER_EMAIL_ADDRESS, null));

        List<String> recipients = new ArrayList<String>();
        recipients.add(context.getString(R.string.exceptionEmailTo));
        email.setRecipients(recipients);

        email.setSubject(context.getString(R.string.exceptionEmailSubject));
        email.setBody(exceptionMsg);
        return email;
    }

    public static Email getEmail(StatusMessage statusMessage, Context context) throws Throwable {
        Email email = new Email();

        String subject = null;
        String body = null;

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        Location location = statusMessage.getLocation();
        TemplateItemContainer.getInstance();
        if (location != null) {
            String emailSubjectHasLocationTemplate = Constants.getProperty(context,
                    R.string.emailSubjectPreferenceName, R.string.emailSubjectHasLocationTemplate);
            String emailBodyHasLocationTemplate = Constants.getProperty(context, R.string.emailBodyPreferenceName,
                    R.string.emailBodyHasLocationTemplate);
            subject = TemplateItemContainer.getInstance().replaceWildcardsWithValues(statusMessage,
                    emailSubjectHasLocationTemplate, context);
            body = TemplateItemContainer.getInstance().replaceWildcardsWithValues(statusMessage,
                    emailBodyHasLocationTemplate, context);
        } else {
            String emailSubjectNoLocationTemplate = Constants.getProperty(context,
                    R.string.emailSubjectNoLocationPreferenceName, R.string.emailSubjectNoLocationTemplate);
            String emailBodyNoLocationTemplate = Constants.getProperty(context,
                    R.string.emailBodyNoLocationPreferenceName, R.string.emailBodyNoLocationTemplate);
            subject = TemplateItemContainer.getInstance().replaceWildcardsWithValues(statusMessage,
                    emailSubjectNoLocationTemplate, context);
            body = TemplateItemContainer.getInstance().replaceWildcardsWithValues(statusMessage,
                    emailBodyNoLocationTemplate, context);
        }

        // Sender/Subject
        email.setSender(prefs.getString(Constants.PREFS_SENDER_EMAIL_ADDRESS, null));
        email.setSubject(subject);

        // Recipients
        email.setRecipients(getRecipients(prefs));
        email.setBody(body);

        return email;
    }

    public static boolean canSendEmail(SharedPreferences prefs) {
        boolean canSend = true;
        String senderEmailAddress = prefs.getString(Constants.PREFS_SENDER_EMAIL_ADDRESS, null);
        if (senderEmailAddress == null || senderEmailAddress.length() == 0) {
            canSend = false;
        }
        String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
        String tokenSecret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
        if (TextUtils.isEmpty(token) || TextUtils.isEmpty(tokenSecret)) {
            canSend = false;
        }
        return canSend;
    }
}
